package main

import "encoding/json"

func main() {
	var a = Person{
		Name: "",
		Age:  0,
	}
	var f = &Person{
		Name: "",
		Age:  0,
	}
	println(a, f)

	var b *Person = new(Person) //new出来结构体为指针
	(*b).Age = 11
	b.Name = "a" // 可省略*

	var c Person = a //复制其他对象值后有自己的内存空间
	println(c)

	marshal, err := json.Marshal(a) //序列化
	println(marshal, err)

	a.test(1)
	b.test(1)

	var af [2]Object //多态
	af[0] = Person{}
	af[1] = Human{}

	//类型断言
	var s2 interface{}
	s2 = Person{} //由空接口指向结构体
	var v1 Person
	v1 = s2.(Person) //接口转实例
	println(v1)
	if v2, ok := s2.(Person); ok {
		println(v2)
	}

}

type Object interface {
}
type Person struct { //结构体
	//因为json需要对象的属性大写为全局 Name Age
	//tag指名在其他包中属性的别名
	Name string `json:"name"`
	Age  int    `json:"age"`
}

type Human struct {
	Phone int
}

type Student struct {
	Person        //继承  公私有字段/方法都可以使用
	person Person //组合 调用时student.person.test1
	id     int
	int          //匿名字段  student.int
	human  Human //多重继承
	aaTest       //接口
}

// person写与不写都可  (形参)
func (person Person) test(int) int { //指定方法绑定的结构体
	return 1
}

//函数形参为值类型只能传值
//方法形参为值类型可传指针  但是值拷贝不影响原指针指向的原变量
//方法形参为指针可传值  值指向地址

func NewPerson(n string, a int) *Person { //工厂模式
	return &Person{
		Name: n,
		Age:  a,
	}
}

func (p *Person) SetName(name string) {
	p.Name = name
}

type aaTest interface { //接口
	Eat()
	Sleep()
}

func (p Person) Eat() { //指定方法绑定的结构体

}
